package com.united.ucts.modules.juc.lock;

import lombok.SneakyThrows;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author hudan
 * @version 1.0
 * @filename ThreadCommunication.java
 * @copyright <a href="www.chancein.com">www.chancein.com</a>
 * @date 2022-09-28
 */
public class ThreadCommunication {
}


// 第一步创建资源类
class ShareResource {
    // 定义标志位,默认第一个线程标志位为1; 后面的每一个累加1
    private int flag = 1;
    // 创建Lock锁
    private Lock lock = new ReentrantLock();
    // 创建Condtion
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    /**
     * 具体的资源方法， 打印5次线程数据, 参数为第几轮
     */
    @SneakyThrows
    public void print5(int loop) {
        // 上锁
        lock.lock();
        try {
            // 判断标志位
            while (flag != 1) {
                // 等待处理
                condition1.await();
            }

            // 干活处理
            for (int i = 1; i <= 5; i++) {
                System.out.println(Thread.currentThread().getName() + "::" + i + ":轮数:" + loop);
            }

            // 通知(先修改全局标志位,再通知)
            flag = 2;
            condition2.signal();
        } finally {
            // 释放锁
            lock.unlock();
        }
    }

    /**
     * 具体的资源方法， 打印10次线程数据, 参数为第几轮
     */
    @SneakyThrows
    public void print10(int loop) {
        // 上锁
        lock.lock();
        try {
            // 判断标志位
            while (flag != 2) {
                // 等待处理
                condition2.await();
            }

            // 干活处理
            for (int i = 1; i <= 10; i++) {
                System.out.println(Thread.currentThread().getName() + "::" + i + ":轮数:" + loop);
            }

            // 通知(先修改全局标志位,再通知)
            flag = 3;
            condition3.signal();
        } finally {
            // 释放锁
            lock.unlock();
        }
    }

    /**
     * 具体的资源方法， 打印15次线程数据, 参数为第几轮
     */
    @SneakyThrows
    public void print15(int loop) {
        // 上锁
        lock.lock();
        try {
            // 判断标志位
            while (flag != 3) {
                // 等待处理
                condition3.await();
            }

            // 干活处理
            for (int i = 1; i <= 15; i++) {
                System.out.println(Thread.currentThread().getName() + "::" + i + ":轮数:" + loop);
            }

            // 通知(先修改全局标志位,再通知)
            flag = 1;
            condition1.signal();
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
}